#include "U2GLESDepthBuffer.h"

#include "U2GLESHardwarePixelBuffer.h"
#include "U2GLESRenderSystem.h"
#include "U2GLESFrameBufferObject.h"


U2EG_NAMESPACE_USING


U2GLESDepthBuffer::U2GLESDepthBuffer( u2uint16 poolId, GLESRenderSystem *renderSystem, U2GLESContext *creatorContext,
								GLESRenderBuffer *depth, GLESRenderBuffer *stencil,
								u2uint32 width, u2uint32 height, u2uint32 fsaa, u2uint32 multiSampleQuality,
								bool isManual )
: U2DepthBuffer( poolId, 0, width, height, fsaa, "", isManual )
, mMultiSampleQuality( multiSampleQuality )
, mCreatorContext( creatorContext )
, mDepthBuffer( depth )
, mStencilBuffer( stencil )
, mRenderSystem( renderSystem )
{
	if( mDepthBuffer )
	{
		switch( mDepthBuffer->getGLFormat() )
		{
#if GL_OES_framebuffer_object
		case GL_DEPTH_COMPONENT16_OES:
			mBitDepth = 16;
			break;
#endif

#if GL_OES_packed_depth_stencil
        case GL_DEPTH24_STENCIL8_OES:  // Packed depth / stencil
#endif
#if GL_OES_depth24
		case GL_DEPTH_COMPONENT24_OES:
			mBitDepth = 32;
			break;
#endif
		}
	}
}

U2GLESDepthBuffer::~U2GLESDepthBuffer()
{
	if( mStencilBuffer && mStencilBuffer != mDepthBuffer )
	{
		delete mStencilBuffer;
		mStencilBuffer = 0;
	}

	if( mDepthBuffer )
	{
		delete mDepthBuffer;
		mDepthBuffer = 0;
	}
}
//---------------------------------------------------------------------
bool U2GLESDepthBuffer::isCompatible( U2RenderTarget *renderTarget ) const
{
	bool retVal = false;

	//Check standard stuff first.
	if( mRenderSystem->getCapabilities()->hasCapability( RSC_RTT_DEPTHBUFFER_RESOLUTION_LESSEQUAL ) )
	{
		if( !U2DepthBuffer::isCompatible( renderTarget ) )
			return false;
	}
	else
	{
		if( this->getWidth() != renderTarget->getWidth() ||
			this->getHeight() != renderTarget->getHeight() ||
			this->getFsaa() != renderTarget->getFSAA() )
				return false;
	}

	//Now check this is the appropriate format
	GLESFrameBufferObject *fbo = 0;
    renderTarget->getCustomAttribute("FBO", &fbo);

	if( !fbo )
	{
		U2GLESContext *windowContext;
		renderTarget->getCustomAttribute( "GLCONTEXT", &windowContext );

		//Non-FBO targets and FBO depth surfaces don't play along, only dummies which match the same
		//context
		if( !mDepthBuffer && !mStencilBuffer && mCreatorContext == windowContext )
			retVal = true;
	}
	else
	{
		//Check this isn't a dummy non-FBO depth buffer with an FBO target, don't mix them.
		//If you don't want depth buffer, use a Null Depth Buffer, not a dummy one.
		if( mDepthBuffer || mStencilBuffer )
		{
			GLenum internalFormat = fbo->getFormat();
			GLenum depthFormat, stencilFormat;
			mRenderSystem->_getDepthStencilFormatFor( internalFormat, &depthFormat, &stencilFormat );

			bool bSameDepth = false;

			if( mDepthBuffer )
				bSameDepth |= mDepthBuffer->getGLFormat() == depthFormat;

			bool bSameStencil = false;

            if( !mStencilBuffer || mStencilBuffer == mDepthBuffer )
               bSameStencil = stencilFormat == GL_NONE;
            else
            {
                if( mStencilBuffer )
                    bSameStencil = stencilFormat == mStencilBuffer->getGLFormat();
            }

			retVal = bSameDepth && bSameStencil;
		}
	}

	return retVal;
}